﻿Imports System.Collections.Specialized
Imports System.IO
Imports System.Globalization
Imports Microsoft.TeamFoundation.Client
Imports Microsoft.TeamFoundation.WorkItemTracking.Client
Imports System.Collections.ObjectModel
Imports System

Imports System.ComponentModel

Imports System.Xml.Serialization

Imports System.Threading

Namespace Controlers

    Public Class HeatControler(Of TView As {UIElement, IHeatView(Of TView)})
        Inherits ControlerBase(Of TView)



        Public Sub New(ByVal View As TView)
            MyBase.New(View)
            Reset()


        End Sub

        Public Overrides Sub Reset()
            UpdateConnection_Async()
        End Sub

#Region " Connection "

        Private m_ServerVersion As Integer = 0

        Public Property ServerVersion() As Integer
            Get
                Return m_ServerVersion
            End Get
            Private Set(ByVal value As Integer)
                If Not value = m_ServerVersion Then
                    m_ServerVersion = value
                    OnPropertyChanged("ServerVersion")
                End If
            End Set
        End Property


        Private m_IsConnected As Boolean = False

        Public Property IsConnected() As Boolean
            Get
                Return m_IsConnected
            End Get
            Private Set(ByVal value As Boolean)
                If Not value = m_IsConnected Then
                    m_IsConnected = value
                    OnPropertyChanged("IsConnected")
                End If
            End Set
        End Property

        Private m_DataContext As Data.HeatDataContext = Nothing

        Friend Property DataContext() As Data.HeatDataContext
            Get
                ' SQL Server 2000 Limitation workaround. Always generate a new DataContect. Pants, but nessesery as MultipleActiveResultSets is not supported.
                If ServerVersion < 9 And IsConnected Then
                    Return New Data.HeatDataContext(m_ConnectionString)
                End If
                Return m_DataContext
            End Get
            Private Set(ByVal value As Data.HeatDataContext)
                If Not value Is m_DataContext Then
                    m_DataContext = value
                    OnPropertyChanged("DataContext")
                    IsConnected = True
                End If
            End Set
        End Property

        Private m_ConnectionStringMask As String = "Server={0};Database={1};Trusted_Connection=yes;MultipleActiveResultSets=True;"
        Private m_ConnectionString As String = ""

        Private Sub UpdateConnection()
            Working = True
            If Not String.IsNullOrEmpty(My.Settings.HeatCatalog) And Not String.IsNullOrEmpty(My.Settings.HeatDataSource) Then
                ConnectionState = System.Data.ConnectionState.Connecting
                m_ConnectionString = String.Format(m_ConnectionStringMask, My.Settings.HeatDataSource, My.Settings.HeatCatalog)
                Try
                    Dim c As New System.Data.SqlClient.SqlConnection(m_ConnectionString)
                    AddHandler c.StateChange, AddressOf Connection_StateChange
                    AddHandler c.InfoMessage, AddressOf Connection_InfoMessage
                    c.Open()
                    If c.ServerVersion.StartsWith("08") Then
                        ServerVersion = 8
                    End If
                    ' MsgBox(Connection)
                    DataContext = New Data.HeatDataContext(c)
                    DataContext.CommandTimeout = 1000
                    DataContext.DatabaseExists()
                    UpdateApplications_Async()
                Catch ex As Exception
                    ConnectionState = System.Data.ConnectionState.Broken
                End Try
            End If
            Working = False
        End Sub

        Public Sub UpdateConnection_Async()
            Dim action As New Action(AddressOf UpdateConnection)
            action.BeginInvoke(New AsyncCallback(AddressOf UpdateApplication), Nothing)
        End Sub

        Private m_ConnectionInfoMessage As String

        Public Property ConnectionInfoMessage() As String
            Get
                Return m_ConnectionInfoMessage
            End Get
            Private Set(ByVal value As String)
                If Not value = m_ConnectionInfoMessage Then
                    m_ConnectionInfoMessage = value
                    OnPropertyChanged("ConnectionInfoMessage")
                End If
            End Set
        End Property

        Private m_ConnectionErrors As System.Data.SqlClient.SqlErrorCollection

        Public Property ConnectionErrors() As System.Data.SqlClient.SqlErrorCollection
            Get
                Return m_ConnectionErrors
            End Get
            Private Set(ByVal value As System.Data.SqlClient.SqlErrorCollection)
                If Not value Is m_ConnectionErrors Then
                    m_ConnectionErrors = value
                    OnPropertyChanged("ConnectionErrors")
                End If
            End Set
        End Property

        Private Sub Connection_InfoMessage(ByVal sender As Object, ByVal e As System.Data.SqlClient.SqlInfoMessageEventArgs)
            ConnectionInfoMessage = e.Message
            ConnectionErrors = e.Errors
        End Sub

        Private m_ConnectionState As System.Data.ConnectionState

        Public Property ConnectionState() As System.Data.ConnectionState
            Get
                Return m_ConnectionState
            End Get
            Private Set(ByVal value As System.Data.ConnectionState)
                If Not value = m_ConnectionState Then
                    m_ConnectionState = value
                    OnPropertyChanged("ConnectionState")
                End If
            End Set
        End Property

        Private Sub Connection_StateChange(ByVal sender As Object, ByVal e As System.Data.StateChangeEventArgs)
            ConnectionState = e.CurrentState
        End Sub

#End Region

#Region " Application "

        Private m_SelectedApplication As String
        Private m_HasSelectedApplication As Boolean = False

        Public Property SelectedApplication() As String
            Get
                Return m_SelectedApplication
            End Get
            Set(ByVal value As String)
                m_SelectedApplication = value
                My.Settings.SelectedHeatApplication = value
                OnPropertyChanged("SelectedApplication")
                HasSelectedApplication = True
            End Set
        End Property

        Public Property HasSelectedApplication() As Boolean
            Get
                Return m_HasSelectedApplication
            End Get
            Private Set(ByVal value As Boolean)
                If Not value = m_HasSelectedApplication Then
                    m_HasSelectedApplication = value
                    OnPropertyChanged("HasApplication")
                End If
            End Set
        End Property

        Public Sub UpdateApplication()
            If Not String.IsNullOrEmpty(My.Settings.SelectedHeatApplication) And Not ApplicationChoices Is Nothing Then
                If ApplicationChoices.Contains(My.Settings.SelectedHeatApplication) Then
                    SelectedApplication = My.Settings.SelectedHeatApplication
                Else
                    SelectedApplication = String.Empty
                End If
            End If
        End Sub


#End Region

        Private Sub UpdateApplications_Async()
            Dim a As New Action(AddressOf UpdateApplications)
            a.BeginInvoke(Nothing, Nothing)
        End Sub

        Private m_Applications As Collection(Of String)

        Public Property ApplicationChoices() As IEnumerable(Of String)
            Get
                Return m_Applications
            End Get
            Private Set(ByVal value As IEnumerable(Of String))
                If Not value Is m_Applications Then
                    m_Applications = value
                    OnPropertyChanged("ApplicationChoices")
                End If
            End Set
        End Property

        Private Sub UpdateApplications()
            If IsConnected Then
                Dim newApps As New Collection(Of String)
                Dim v = From x In DataContext.CallLogs Select x.Application Distinct
                For Each s As String In v
                    newApps.Add(s)
                Next
                ApplicationChoices = newApps
                UpdateApplication()
            End If
        End Sub

        Public Function ApplicationsList() As IQueryable(Of Data.Entities.CallLog)
            If Not IsConnected Then
                Return Nothing
            End If
            Return From x In DataContext.CallLogs _
                   Where x.Application = SelectedApplication _
                   And Not x.CallStatus = "Closed" _
                   Order By x.CallID
        End Function


        Public ReadOnly Property PendingApplications() As IEnumerable(Of Data.Entities.CallLog)
            Get
                If Not IsConnected Then
                    Return Nothing
                End If
                Return From x In ApplicationsList() _
                       Where Not x.RefNo.StartsWith("TFS")
            End Get
        End Property

        Public ReadOnly Property ConnectedApplications() As IEnumerable(Of Data.Entities.CallLog)
            Get
                If Not IsConnected Then
                    Return Nothing
                End If
                Return From x In ApplicationsList() _
                       Where x.RefNo.StartsWith("TFS")
            End Get
        End Property

        Public Function GetCallLog(ByVal callID As Integer) As Data.Entities.CallLog
            If Not IsConnected Then
                Return Nothing
            End If
            Dim v = (From x In DataContext.CallLogs Where x.CallID = callID).SingleOrDefault
            If Not v Is Nothing Then
                Return v
            End If
            Return Nothing
        End Function

        Public Function GetCallLogsTFSRef(ByVal RefNo As String) As Integer
            Dim witid As Integer = 0
            If Not RefNo Is Nothing AndAlso RefNo.StartsWith("TFS") AndAlso RefNo.Contains("\") Then
                Dim bits() As String = RefNo.Split("\")
                If bits.Length = 2 Then
                    If IsNumeric(bits(1)) Then
                        Return CInt(bits(1))
                    End If
                End If
            End If
            Return 0
        End Function


    End Class

End Namespace